import { typedHttp } from '@/utils/typedHttp';
import { type SystemSettings } from '@/types/setting';
import OpenAI from 'openai';

/**
 * API响应中的设置项接口
 * 注意：这里需要和后端API返回的结构匹配
 */
interface ApiSettingsResponse {
  id?: number;
  api_url: string;
  api_key: string;
  model: string;
}

/**
 * 创建/更新设置的请求体
 */
interface SaveSettingsRequest {
  api_url: string;
  api_key: string;
  model: string;
}

/**
 * 分页查询参数
 */
interface PaginationParams {
  skip?: number;
  limit?: number;
}

/**
 * 将API响应转换为SystemSettings格式
 */
const mapApiToSystemSettings = (apiSettings: ApiSettingsResponse): SystemSettings => {
  // 如果模型接口地址为host.docker.internal,替换为localhost
  if (apiSettings.api_url.includes("host.docker.internal")) {
    apiSettings.api_url = apiSettings.api_url.replace("host.docker.internal", "localhost");
  }

  return {
    model: {
      apiUrl: apiSettings.api_url,
      apiKey: apiSettings.api_key,
      model: apiSettings.model
    },
    general: {},
    advanced: {}
  };
};

/**
 * 将SystemSettings转换为API请求格式
 */
const mapToApiRequest = (settings: SystemSettings): SaveSettingsRequest => {
  return {
    api_url: settings.model.apiUrl,
    api_key: settings.model.apiKey,
    model: settings.model.model
  };
};


/**
 * 测试OpenAI API连接
 * @param apiUrl API地址
 * @param apiKey API密钥
 * @param model 要测试的模型名称
 * @returns 返回连接是否成功
 * @throws 包含具体错误信息的Error对象
 */
export const mockTestConnection = async (apiUrl: string, apiKey: string, model: string): Promise<boolean> => {
  if (!apiUrl) {
    throw new Error('API地址不能为空');
  }
  if (!model) {
    throw new Error('模型名称不能为空');
  }

  try {
    // 创建OpenAI客户端实例
    const openai = new OpenAI({
      apiKey: apiKey,
      baseURL: apiUrl,
      dangerouslyAllowBrowser: true,
      maxRetries: 1, // 减少重试次数，快速失败
      timeout: 60000, // 60秒超时
    });

    // 测试模型是否能正常响应（发送一个简单的提示）
    const testPrompt = 'Hello';
    const response = await openai.chat.completions.create({
      model: model,
      messages: [
        { role: 'system', content: 'You are a helpful assistant.' },
        { role: 'user', content: testPrompt }
      ],
      max_tokens: 5, // 最小化token使用
      temperature: 0,
    });
    
    // 验证响应是否有效
    if (!response.choices || response.choices.length === 0) {
      throw new Error('模型响应无效');
    }
    
    return true;
  } catch (error) {
    console.error('API连接测试失败:', error);
    
    // 处理不同类型的错误
    if (error instanceof Error) {
      const errorMessage = error.message.toLowerCase();
      
      if (errorMessage.includes('invalid api key') || errorMessage.includes('401')) {
        throw new Error('API密钥无效或已过期');
      } else if (errorMessage.includes('not found') || errorMessage.includes('404')) {
        throw new Error('API端点不存在，请检查URL是否正确');
      } else if (errorMessage.includes('econnrefused') || errorMessage.includes('failed to fetch')) {
        throw new Error('无法连接到API服务器，请检查网络连接和URL');
      } else if (errorMessage.includes('timeout') || errorMessage.includes('time out')) {
        throw new Error('连接超时，请检查网络连接或稍后再试');
      } else if (errorMessage.includes('rate limit')) {
        throw new Error('请求频率超限，请稍后再试');
      } else if (errorMessage.includes('server error') || errorMessage.includes('50')) {
        throw new Error('服务器内部错误，请稍后再试');
      }
    }
    
    // 返回通用错误信息
    throw new Error(`连接测试失败: ${(error as Error).message}`);
  }
};

/**
 * 获取所有设置项
 * @param params 分页参数
 * @returns 设置项列表
 */
export const getSettings = async (params?: PaginationParams): Promise<SystemSettings[]> => {
  try {
    // 显式指定返回类型为 ApiSettingsResponse[]
    const savedSettings = await typedHttp.get<ApiSettingsResponse[]>('/settings/', { params }) as unknown as ApiSettingsResponse[];
    return (savedSettings || []).map(mapApiToSystemSettings);
  } catch (error) {
    console.error('获取设置失败:', error);
    throw error;
  }
};


/**
 * 创建新的设置项
 * @param settings 设置项数据
 * @returns 是否保存成功
 */
export const mockSaveSettings = async (settings: SystemSettings): Promise<boolean> => {
  try {
    const requestData = mapToApiRequest(settings);
    await typedHttp.post<ApiSettingsResponse>('/settings/', requestData);
    return true;
  } catch (error) {
    console.error('保存设置失败:', error);
    return false;
  }
};



/**
 * 保存设置（创建或更新）
 * @param settings 设置项数据
 * @returns 是否保存成功
 */
export const saveSettings = async (settings: SystemSettings & { id?: number }): Promise<boolean> => {
  try {
    // 创建新设置
    return await mockSaveSettings(settings);
  } catch (error) {
    console.error('保存设置失败:', error);
    return false;
  }
};